{
    "cells": [
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "<i>Copyright (c) Recommenders contributors.</i>\n",
                "\n",
                "<i>Licensed under the MIT License.</i>"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "# Template\n",
                "\n",
                "Title of the notebooks should be concise and it's at heading-1 level, i.e., with one \"#\" in the markdown code."
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Right under the notebook title, a brief introduction of the notebook is placed. Usually this will be what technical/business problems that the technical contents in this notebook try to solve."
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "**Example**:"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "This notebook shows how to set a version check for Recommenders."
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## 0 Global settings"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Heading-2 level is for each sections in the notebook. It starts from 0, where it is usually about global settings such as module imports, global variable definitions, etc. \n",
                "Name of the section starts with a capital letter. "
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### Module imports\n",
                "\n",
                "It is a good practice to add all the imports in the first cell. "
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 1,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "System version: 3.9.16 (main, May 15 2023, 23:46:34) \n",
                        "[GCC 11.2.0]\n",
                        "Recommenders version: 1.1.1\n"
                    ]
                }
            ],
            "source": [
                "import sys\n",
                "\n",
                "import recommenders\n",
                "from recommenders.utils.notebook_utils import store_metadata\n",
                "\n",
                "print(f\"System version: {sys.version}\")\n",
                "print(f\"Recommenders version: {recommenders.__version__}\")"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### Global variables"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "For the convenience of parameterizing notebook tests, tagging of \"parameters\" can be added to the cell such that variables in the cell can be found by `papermill` in testing. "
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 2,
            "metadata": {
                "tags": [
                    "parameters"
                ]
            },
            "outputs": [],
            "source": [
                "RECOMMENDERS_VERSION = \"0.1.1\""
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## 1 Section1"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Each of the sections can be hierarchical. Level numbers are connect by \".\". "
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### 1.1 Sub-section1"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Note that \n",
                "1. The Python codes in the notebook should follow PEP standard.\n",
                "2. The code should be formatted with Black."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 3,
            "metadata": {},
            "outputs": [],
            "source": [
                "def check_version(version, current_version):\n",
                "    v1_parts = version.split(\".\")\n",
                "    v2_parts = current_version.split(\".\")\n",
                "\n",
                "    # Pad the version parts with zeros to ensure equal length\n",
                "    max_parts = max(len(v1_parts), len(v2_parts))\n",
                "    v1_parts.extend([\"0\"] * (max_parts - len(v1_parts)))\n",
                "    v2_parts.extend([\"0\"] * (max_parts - len(v2_parts)))\n",
                "\n",
                "    for v1, v2 in zip(v1_parts, v2_parts):\n",
                "        if int(v1) <= int(v2):\n",
                "            print(f\"{version} is older than {current_version}\")\n",
                "            return True\n",
                "        elif int(v1) > int(v2):\n",
                "            print(f\"Error: {version} is newer than {current_version}\")\n",
                "            raise ValueError\n"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 4,
            "metadata": {},
            "outputs": [
                {
                    "name": "stdout",
                    "output_type": "stream",
                    "text": [
                        "0.1.1 is older than 1.1.1\n"
                    ]
                }
            ],
            "source": [
                "checked_version = check_version(RECOMMENDERS_VERSION, recommenders.__version__)"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Codes in a notebook are tested with `store_metadata`. Below the example shows how to record a variable for testing purpose."
            ]
        },
        {
            "cell_type": "code",
            "execution_count": 5,
            "metadata": {},
            "outputs": [
                {
                    "data": {
                        "application/notebook_utils.json+json": {
                            "data": true,
                            "encoder": "json",
                            "name": "checked_version"
                        }
                    },
                    "metadata": {
                        "notebook_utils": {
                            "data": true,
                            "display": false,
                            "name": "checked_version"
                        }
                    },
                    "output_type": "display_data"
                }
            ],
            "source": [
                "store_metadata(\"checked_version\", checked_version)"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "#### 1.1.1 Sub-sub-section"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "### 1.2 Sub-section2"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## 2 Section2"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## References\n",
                "\n",
                "It is highly encouraged to have references for technical explanations in the notebooks for people to easily understand theories and reproduce codes. "
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "**Example:**\n",
                "    \n",
                "1. Jianxu Lian et al, \"xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems\", Proc. ACM KDD, London, UK, 2018, pp. 1754-1763.\n",
                "2. PySpark MLlib evaluation metrics, url: https://spark.apache.org/docs/2.3.0/mllib-evaluation-metrics.html"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "Note this section, which is not the body sections of the notebook, does not have to be numbered in section name. "
            ]
        }
    ],
    "metadata": {
        "celltoolbar": "Tags",
        "kernelspec": {
            "display_name": "recommenders",
            "language": "python",
            "name": "python3"
        },
        "language_info": {
            "codemirror_mode": {
                "name": "ipython",
                "version": 3
            },
            "file_extension": ".py",
            "mimetype": "text/x-python",
            "name": "python",
            "nbconvert_exporter": "python",
            "pygments_lexer": "ipython3",
            "version": "3.9.16"
        }
    },
    "nbformat": 4,
    "nbformat_minor": 2
}
